package com.zx.zxapiorder.utils;

import cn.hutool.core.util.IdUtil;
import com.zx.zxapicommon.constant.RedisConstant;
import com.zx.zxapiorder.model.entity.ApiOrder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import static com.zx.zxapicommon.constant.RabbitmqConstant.*;

/**
 * @author 张旭
 * @version 1.0
 */
@Slf4j
@Component
public class RabbitOrderUtils implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    private Long finalId = null;

    /**
     * 向mq发送订单消息
     * @param order
     */
    public void sendOrderSnInfo(ApiOrder order) {
        finalId = order.getId();
        //将订单缓存到redis中
        redisTemplate.opsForValue().set(RedisConstant.SEND_ORDER_PREFIX + order.getId(), String.valueOf(order));
        String finalMessageId = IdUtil.simpleUUID();
        //将订单信息发送到mq中
        rabbitTemplate.convertAndSend(ORDER_EXCHANGE_NAME, ORDER_SEND_EXCHANGE_ROUTING_KEY, order, message -> {
            MessageProperties messageProperties = message.getMessageProperties();
            //生成全局唯一id
            messageProperties.setMessageId(finalMessageId);
            messageProperties.setContentEncoding("utf-8");
            return message;
        });
    }

    /**
     * 只要消息抵达服务器，那么b=ture
     *
     * @param correlationData 当前消息的唯一关联数据（消息的唯一id）
     * @param b               消息是否成功收到
     * @param s               失败的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        if (b) {
            //投递成功，删除redis中的向mq发送的订单内容
            redisTemplate.delete(RedisConstant.SEND_ORDER_PREFIX + finalId);
        } else {
            log.error("订单--消息投递到服务端失败：{}---->{}", correlationData, s);
        }
    }

    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.error("发生异常，返回消息回调:{}", returnedMessage);
    }

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }
}
